#include "ToolFakeSelect.h"

ToolFakeSelect::ToolFakeSelect()
: rend(RenderManager::getInstance()), global(GlobalStates::getInstance()),
  dragging(false),scale(0),operation(NONE),axis(ALL)
{
    tempPos=vector3<int>(0,0,0);
}

Tool* ToolFakeSelect::getInstance()
{
    static Tool* inst=0;
    if(!inst)inst = (Tool*)(new ToolFakeSelect());
    return inst;
}

void ToolFakeSelect::overlayDisplay(){
    if(operation==SCALING)
        Drawing::drawLine2D(WIN_X_HALF,WIN_Y_HALF,mousePos.x, mousePos.y);

}

void ToolFakeSelect::operationHandler(){
    vector3<int> normal = (end3d-start3d)/2;
    glPushMatrix();
    glTranslated(start3d.x+normal.x,start3d.y+normal.y,start3d.z+normal.z);

    if(operation==SCALING){
        if(axis==ALL)glScalef(scale,scale,scale);
        else glScalef(axis==X_AXIS?scale:1,
                      axis==Y_AXIS?scale:1,
                      axis==Z_AXIS?scale:1);
    }
    else if(operation==TRANSLATING){
        glTranslated(tempPos.x,tempPos.y,tempPos.z);
    }
    Drawing::drawWireCuboid(-normal,normal);
    glPopMatrix();
}

void ToolFakeSelect::display(){
    if(operation==NONE)Drawing::drawWireCuboid(start3d,end3d);
    else operationHandler();
}

Result ToolFakeSelect::mouseMoveEvent(QMouseEvent *event){
    mousePos = vector2<int>(event->x(), event->y());

    if(dragging)
        end3d=rend->mouseUtils.getMouseOverVoxelPt(mousePos.x, mousePos.y);
    else if(operation==SCALING)
        scale = (mousePos-vector2<int>(WIN_X_HALF,WIN_Y_HALF)).mag()/100;

    return Result(true);
}

Result ToolFakeSelect::mousePressEvent(QMouseEvent *event){
    if(!dragging){

        start=mousePos=vector2<int>(event->x(), event->y());
        start3d=rend->mouseUtils.getMouseOverVoxelPt(start.x,start.y);
        dragging=true;

    }
    return Result(true);
}

Result ToolFakeSelect::mouseReleaseEvent(QMouseEvent *event){
    if(dragging){
        dragging=false;
        end3d=rend->mouseUtils.getMouseOverVoxelPt(mousePos.x, mousePos.y);
        start=mousePos=vector2<int>(0,0);
        //for loop to add
        int itrx = GET_INT_SIGN(end3d.x-start3d.x),
            itry = GET_INT_SIGN(end3d.y-start3d.y),
            itrz = GET_INT_SIGN(end3d.z-start3d.z);

        for(int i=start3d.x; i!=end3d.x+itrx ; i+=itrx)
            for(int j=start3d.y; j!=end3d.y+itry ; j+=itry)
                for(int k=start3d.z; k!=end3d.z+itrz ; k+=itrz){
                    if(rend->getVoxel(i,j,k).draw()){
                        colour col = colourMask(rend->getVoxelColor(i,j,k));
                        rend->setVoxelColor(i,j,k,col);
                    }
                }

    }
    return Result(true);
}

Result ToolFakeSelect::keyPressEvent(QKeyEvent *event){
    switch(event->key()){
    case Qt::Key_S:
        operation=SCALING;
        break;
    case Qt::Key_T:
        operation=TRANSLATING;
        tempPos=vector3<int>(0,0,0);
        axis=ALL;
        break;
    case Qt::Key_X:
        axis=X_AXIS;
        break;
    case Qt::Key_Y:
        axis=Y_AXIS;
        break;
    case Qt::Key_Z:
        axis=Z_AXIS;
        break;
    case Qt::Key_Escape:
        axis=ALL;
        operation=NONE;
        break;
    default:
        if(operation==TRANSLATING)axis=ALL;
        break;
    }

    if(operation==TRANSLATING){
        if(axis!=ALL){
        vector3<int> trans(axis==X_AXIS,axis==Y_AXIS,axis==Z_AXIS);
        if(event->modifiers() & Qt::ShiftModifier) trans = -trans;
        if(!(event->modifiers() & Qt::ControlModifier))trans *= 5;
        tempPos+=trans;
        }
    }

    return Result(true);
}
